package com.sky.controller.user;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.properties.JwtProperties;
import com.sky.properties.WeChatProperties;
import com.sky.result.Result;
import com.sky.service.UserService;
import com.sky.utils.HttpClientUtil;
import com.sky.utils.JwtUtil;
import com.sky.vo.UserLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@Api(tags = "用户相关接口")
@RequestMapping("/user/user")
@RestController
@Slf4j
public class UserController {

    /**
     * 微信服务器提供的接口地址
     */
    private static final String WX_URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private UserService userService;

    /**
     * 微信登录
     * @link https://developers.weixin.qq.com/ebook?action=get_post_info&docid=000cc48f96c5989b0086ddc7e56c0a
     * @link https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
     * @param userLoginDTO 用户登录信息
     * @return 登录成功的结果
     */
    @ApiOperation(value = "微信登录")
    @PostMapping("/login")
    public Result<UserLoginVO> wxLogin(@RequestBody UserLoginDTO userLoginDTO) {
        // 根据用户提交的微信登录凭证code，到微信服务器换取微信用户身份openid
        String openid = getOpenIdByCode(userLoginDTO.getCode());
        // 根据 openid 查询用户
        User user = userService.getByOpenid(openid);
        if(user == null) {
            // 注册/新增用户，返回最新用户id
            user = userService.addUser(openid);
        }
        // 根据用户id生成token
        Long id = user.getId();
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, id);
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
        // 返回响应结果
        return Result.success(new UserLoginVO(id, openid, token));
    }

    /**
     * 根据 code 获取 openid
     * @param code 微信登录凭证
     * @return 微信用户身份
     */
    private String getOpenIdByCode(String code) {
        // 根据微信提供接口地址，拼接必填参数
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("appid", weChatProperties.getAppid());
        paramMap.put("secret", weChatProperties.getSecret());
        paramMap.put("js_code", code);
        paramMap.put("grant_type", "authorization_code");
        // 利用 HttpClient 发送 GET 请求
        String jscode2session = HttpClientUtil.doGet(WX_URL, paramMap);
        // 解析字符串，获取 openid 值
        JSONObject jsonObject = JSON.parseObject(jscode2session);
        return jsonObject.getString("openid");
    }
}
